package agitext

import (
	"bytes"
	"context"
	"encoding/base64"
	"os"

	"github.com/opentracing/opentracing-go"
	"google.golang.org/grpc/metadata"
)

const _AGitTracingEnvKey = "AGIT_TRACING_CARRIER"

// AGitStartSpanFromEnv starts an opentracing span from env AGIT_TRACING_CARRIER
func AGitStartSpanFromEnv(ctx context.Context, operationName string, opts ...opentracing.StartSpanOption) (opentracing.Span, context.Context) {
	carrierContent := os.Getenv(_AGitTracingEnvKey)
	if carrierContent == "" {
		return opentracing.StartSpanFromContext(ctx, operationName, opts...)
	}

	decodedContent, err := base64.StdEncoding.DecodeString(carrierContent)
	if err != nil {
		return opentracing.StartSpanFromContext(ctx, operationName, opts...)
	}

	spanFromEnv, err := opentracing.GlobalTracer().Extract(opentracing.Binary, bytes.NewReader(decodedContent))
	if err != nil {
		return opentracing.StartSpanFromContext(ctx, operationName, opts...)
	}

	opts = append(opts, opentracing.ChildOf(spanFromEnv))
	span := opentracing.StartSpan(operationName, opts...)
	finalCtx := opentracing.ContextWithSpan(ctx, span)

	carrier := metadataTextMap{}
	if err := opentracing.GlobalTracer().Inject(spanFromEnv, opentracing.HTTPHeaders, carrier); err == nil {
		// magically inject metadata into context, fake what server should do
		finalCtx = metadata.NewOutgoingContext(finalCtx, metadata.MD(carrier))
	}

	return span, finalCtx
}
